﻿using System;

namespace GBU.Ios.Bll
{
    public class StepCounter
    {
        private static float mLimit = 10;
        static float[] mLastValues = new float[3 * 2];
        static float[] mScale = new float[2];
        private static float mYOffset;

        static float[] mLastDirections = new float[3 * 2];
        private static float[][] mLastExtremes = { new float[3 * 2], new float[3 * 2] };
        static float[] mLastDiff = new float[3 * 2];
        private static int mLastMatch = -1;


        public event EventHandler OnStep;

        public StepCounter()
        {
            int h = 480; // this constan maybe removed at last update.//放大系数
            mYOffset = h * 0.5f;
            mScale[0] = -(h * 0.5f * (1.0f / (Consts.StandardGravity * 2))); //重力加速度放大系数
            mScale[1] = -(h * 0.5f * (1.0f / (Consts.MagneticFieldEarthMax)));//地球磁场上限放大系数
        }

        /// <summary>
        /// 设置加速度敏感度,默认值为:10;
        /// </summary>
        /// <param name="sensitivity"></param>
        /// <remarks>常用敏感系数:  1.97  2.96  4.44  6.66  10.00  15.00  22.50  33.75  50.62</remarks>
        public void SetSensitivity(float sensitivity)
        {
            mLimit = sensitivity;
        }

        public void ComputeStep(float[] values)
        {
            try
            {
                int j = 1; //always was Acceleration sensor
                float vSum = 0;
                float v = 0;

                for (int i = 0; i < 3; i++)
                {
                    v = mYOffset + values[i] * mScale[j]; //当当前传感器为加速度计时,获取三个轴向的值,并使用重力加速度系数进行放大,并在Y轴方向进行偏移.
                    vSum += v;
                }

                //当当前传感器为其他传感器时,例如 磁场传感器
                int k = 0;
                v = vSum / 3; //因之前是将三个轴向的加速度偏移量叠加,此处将其变换为单一轴向的平均加速度偏移量

                float direction = (v > mLastValues[k] ? 1 : (v < mLastValues[k] ? -1 : 0));
                if (direction == -mLastDirections[k])
                {
                    //当方向变化
                    int extType = (direction > 0 ? 0 : 1); //最大或最小值
                    mLastExtremes[extType][k] = mLastValues[k];
                    float diff = Math.Abs(mLastExtremes[extType][k] - mLastExtremes[1 - extType][k]);
                    if (diff > mLimit)
                    {
                        bool isLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3); //是否大于以前的值
                        bool isPreviousLargeEnough = mLastDiff[k] > (diff / 3); //以前的值是否足够大
                        bool isNotContra = (mLastMatch != 1 - extType); //是否不是反方向

                        if (isLargeAsPrevious && isPreviousLargeEnough && isNotContra)
                        {
                           // Log.Debug("StepCounter", "One Step get.");
                            //判定为一步
                            // 通知步频
                            if (OnStep != null)
                            {
                                OnStep(this,new EventArgs());
                            }

                            mLastMatch = extType;
                        }
                        else
                        {
                            //不算做一步,
                            mLastMatch = -1;

                        }
                    }

                    mLastDiff[k] = diff;
                }

                mLastDirections[k] = direction;
                mLastValues[k] = v;
            }
            catch (Exception e)
            {
              //  Log.Debug("StepCounter", e.Message);
                throw e;
            }
        }

    }
}
